package com.atguigu.gulimall.search.thread;

import java.util.concurrent.*;

/**
 * @Author Chill_Lyn
 * @Date 2020/6/19 20:18
 */
public class TestCompletableFuture {

    public static ExecutorService executor=new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20));

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /**
         * 1. 创建异步对象
         */
        // 无返回值
        CompletableFuture.runAsync(()->{
            int i=1+1;
        }, executor);
        // 有返回值
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            return 1 + 1;
        }, executor);
        System.out.println(future.get());

        /**
         * 计算完成时回调方法
         */
        /**
         * 方法处理完成后感知
         */
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            return 1 + 1;
            // 感知到异常，无法修改结果
        }, executor).whenCompleteAsync((result,exception)->{
            System.out.println(result+":"+exception);
            // 感知到异常，同时返回另外值（非结果相关值）
        },executor).exceptionally(exception->{
           return 1+1;
        });

        /**
         * 方法执行完成后处理
         */
        CompletableFuture<Integer> future3 = CompletableFuture.supplyAsync(() -> {
            return 1 + 1;
        }, executor).handle((result,exception)->{
            if(result!=null){
                return  result;
            }
            return -1;
        });
        /**
         * 线程串行化
         */
        //thenRun不能获取上一步的结果，无返回值
        CompletableFuture<Void> future4 = CompletableFuture.supplyAsync(() -> {
            return 1 + 1;
        }, executor).thenRunAsync(()->{
            System.out.println("silence");
        }, executor);

        //thenAccept能接受上一步结果，无返回值
        CompletableFuture<Void> future5 = CompletableFuture.supplyAsync(() -> {
            return 1 + 1;
        }, executor).thenAcceptAsync(System.out::println, executor);

        //thenApply能接受上一步结果，有返回值
        CompletableFuture<Object> future6 = CompletableFuture.supplyAsync(() -> {
            return 1 + 1;
        }, executor).thenApplyAsync(result->{
            return result*2;
        },executor);
        System.out.println(future6.get());

        /**
         * 两任务组合-都要完成
         */

        CompletableFuture<Integer> future7 = CompletableFuture.supplyAsync(() -> {
            System.out.println(1);
            return 1 + 1;
        }, executor);

        CompletableFuture<Integer> future8 = CompletableFuture.supplyAsync(() -> {
            System.out.println(2);
            return 2 + 2;
        }, executor);

        //runAfterBoth不能获取前两者结果
        future7.runAfterBothAsync(future8, ()->{
            System.out.println(3);
        }, executor);
        //thenAcceptBoth获取两者返回值，无返回值
        future7.thenAcceptBothAsync(future8, (r1,r2)->{
            System.out.println(r1+r2);
        },executor);
        //thenCombine获取两者返回值,有返回值
        CompletableFuture<Integer> future9 = future7.thenCombineAsync(future8, Integer::sum, executor);
        System.out.println(future9.get());

        /**
         * 两任务组合-一个完成即可
         */
        //runAfterEither不感知结果，无返回值
        future7.runAfterEitherAsync(future8, ()->{
            System.out.println("one completed");
        }, executor);
        //acceptEither 感知第一个完成的结果，无返回值
        future7.acceptEitherAsync(future8, System.out::println, executor);
        //applyToEither感知第一个完成的结果，有返回值
        future7.applyToEitherAsync(future8, result->{
            return result*2;
        }, executor);

        /**
         * 多任务组合
         */
        CompletableFuture<Integer> future11 = CompletableFuture.supplyAsync(() -> {
            System.out.println(1);
            return 1 + 1;
        }, executor);

        CompletableFuture<Integer> future12 = CompletableFuture.supplyAsync(() -> {
            System.out.println(2);
            return 2 + 2;
        }, executor);

        CompletableFuture<Integer> future13 = CompletableFuture.supplyAsync(() -> {
            System.out.println(3);
            return 3 + 3;
        }, executor);
        // 等待所有任务都完成
        CompletableFuture<Void> allOf = CompletableFuture.allOf(future11, future12, future13);
        //无返回值
        allOf.get();
        System.out.println(future11.get()+":"+future12.get()+":"+future13.get());

        //有一个任务完成，返回值为完成任务的返回值
        CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future11, future12, future13);
        Object o = anyOf.get();


    }
}
